package com.hee.erp.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.CaseFormat;
import com.hee.erp.constant.ConstDictType;
import com.hee.erp.exception.BusinessException;
import com.hee.erp.filter.LoginContextHolder;
import com.hee.erp.modules.entity.*;
import com.hee.erp.modules.mapper.SysUserMapper;
import com.hee.erp.modules.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hee.erp.pojo.SysUserDetail;
import com.hee.erp.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author weizehong
 * @since 2022-03-04
 */
@Service
@Transactional
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Value("${default-pwd}")
    String defaultPwd;
    @Autowired
    ISysUserCertificateService userCertificateService;

    @Autowired
    ISysUserContractService userContractService;

    @Autowired
    ISysUserIdcardService userIdcardService;

    @Autowired
    ISysUserHealthReportService sysUserHealthReportService;

    @Autowired
    ISysUser2RightService sysUser2RightService;

    @Autowired
    ISysDictValueService dictValueService;

    @Autowired
    ISysUserGrowLogService sysUserGrowLogService;

    @Autowired
    ISysUserRemarkService sysUserRemarkService;

    @Autowired
    ISysUserLeaveInfoService sysUserLeaveInfoService;

    @Autowired
    ISysCompanyService sysCompanyService;

    @Autowired
    ISysDepartService departService;

    @Override
    public SysUser login(SysUserLoginVo vo) throws Exception {
        //根据userName获取用户信息
        SysUser user = this.getByUserTel(vo.getUserTel());
        if (user == null) {
            throw new Exception("手机号不存在");
        }
        if (!user.getUserPwd().equals(vo.getUserPwd())) {
            throw new Exception("密码不正确");
        }

        if (user.getDisableFlag() == 1) {
            throw new Exception("账号已禁用");
        }

        return user;
    }

    @Override
    public SysUserDetail getDetailById(String userId) {
        SysUserDetail userDetail = new SysUserDetail();

        //用户基础信息
        SysUser userBasicInfo = this.getById(userId);
        setForeignKey(userBasicInfo);
        userDetail.setUserBasicInfo(userBasicInfo);

        //证书信息
        List<SysUserCertificate> certificateList = userCertificateService.listByUserId(userId);
        userDetail.setCertificateList(certificateList);

        //合同列表
        List<SysUserContract> contractList = userContractService.listByUserId(userId);
        userDetail.setContractList(contractList);

        //合同分类列表
        List<UserContractListProperty> contractPropertyList = userContractService.convertToProperty(contractList);
        userDetail.setContractPropertyList(contractPropertyList);

        //体检报告列表
        List<SysUserHealthReport> healthReportList = sysUserHealthReportService.listByUserId(userId);
        userDetail.setHealthReportList(healthReportList);

        //体检报告分类列表
        List<UserHealthReportListProperty> userHealthReportPropertyList = sysUserHealthReportService.convertToProperty(healthReportList);
        userDetail.setHealthReportPropertyList(userHealthReportPropertyList);

        //身份证信息
        List<SysUserIdcard> idcardList = userIdcardService.listByUserId(userId);
        userDetail.setIdcardList(idcardList);

        //成长日志列表
        List<SysUserGrowLog> growLogList = sysUserGrowLogService.getListByUserId(userId);
        userDetail.setGrowLogList(growLogList);

        //备注列表
        List<SysUserRemark> remarkList = sysUserRemarkService.getListByUserId(userId);
        userDetail.setRemarkList(remarkList);

        //离职信息
        SysUserLeaveInfo leaveInfo = sysUserLeaveInfoService.getByUserId(userId);
        if (leaveInfo == null) {
            leaveInfo = new SysUserLeaveInfo();
            leaveInfo.setUserId(userId);
        }
        userDetail.setLeaveInfo(leaveInfo);

        //配置rightIdList
        List<String> rightIdList = sysUser2RightService.getRightIdListByUserId(userId);
        userDetail.setRightIdList(rightIdList);
        return userDetail;
    }

    private void setForeignKey(SysUser userBasicInfo) {
        //是否手机号登录
        if (userBasicInfo.getPhoneLoginFlag() != null) {
            SysDictValue dictValue = dictValueService.getByTypeAndValue(ConstDictType.YES_OR_NO, userBasicInfo.getPhoneLoginFlag());
            if (dictValue != null) {
                userBasicInfo.setPhoneLoginFlagName(dictValue.getDictName());
            }
        }
        //公司
        if (userBasicInfo.getCompanyId() != null) {
            SysCompany company = sysCompanyService.getById(userBasicInfo.getCompanyId());
            if (company != null) {
                userBasicInfo.setCompanyName(company.getCompanyName());
            }
        }
        //部门
        if (userBasicInfo.getDepartId() != null) {
            SysDepart department = departService.getById(userBasicInfo.getDepartId());
            if (department != null) {
                userBasicInfo.setDepartName(department.getDepartName());
            }
        }
        //性别
        if (userBasicInfo.getSex() != null) {
            SysDictValue dictValue = dictValueService.getByTypeAndValue(ConstDictType.SEX, userBasicInfo.getSex());
            if (dictValue != null) {
                userBasicInfo.setSexName(dictValue.getDictName());
            }
        }
        //民族
        if (userBasicInfo.getNation() != null) {
            SysDictValue dictValue = dictValueService.getByTypeAndValue(ConstDictType.NATION, userBasicInfo.getNation());
            if (dictValue != null) {
                userBasicInfo.setNationName(dictValue.getDictName());
            }
        }
        //政治面貌
        if (userBasicInfo.getPolitical() != null) {
            SysDictValue dictValue = dictValueService.getByTypeAndValue(ConstDictType.POLITICAL, userBasicInfo.getPolitical());
            if (dictValue != null) {
                userBasicInfo.setPoliticalName(dictValue.getDictName());
            }
        }
        //学历
        if (userBasicInfo.getEducation() != null) {
            SysDictValue dictValue = dictValueService.getByTypeAndValue(ConstDictType.EDUCATION, userBasicInfo.getEducation());
            if (dictValue != null) {
                userBasicInfo.setEducationName(dictValue.getDictName());
            }
        }
        //直接上级
        if(StringUtils.isNotBlank(userBasicInfo.getParentId())){
            SysUser parentUser = this.getById(userBasicInfo.getParentId());
            if(parentUser != null){
                userBasicInfo.setParentName(parentUser.getUserName());
            }else{
                userBasicInfo.setParentName("无");
            }
        }else{
            userBasicInfo.setParentName("无");
        }
    }

    @Override
    public void addUser(SysUserVo vo) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(vo, sysUser);
        if (StringUtils.isBlank(sysUser.getUserPwd())) {
            sysUser.setUserPwd(defaultPwd);
        }

        this.checkClockRepeat(sysUser);

        this.save(sysUser);

        List<SysUser2Right> rightList = vo.getRightIds().stream().map(item -> {
            SysUser2Right sysUser2Right = new SysUser2Right();
            sysUser2Right.setUserId(sysUser.getId());
            sysUser2Right.setRightId(item);
            return sysUser2Right;
        }).collect(Collectors.toList());
        if (rightList.size() > 0) {
            sysUser2RightService.saveBatch(rightList);
        }
    }

    @Override
    public Boolean checkTelExists(String userTel) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserTel, userTel);
        long count = this.count(queryWrapper);
        return count > 0;
    }

    @Override
    public Boolean checkUserNoExists(String userNo) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserNo, userNo);
        long count = this.count(queryWrapper);
        return count > 0;
    }

    @Override
    public void disableUser(String id, Integer disableFlag) {
        SysUser user = new SysUser();
        user.setDisableFlag(disableFlag);

        LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SysUser::getId, id);

        this.update(user, wrapper);
    }

    private SysUser getByUserTel(String userTel) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserTel, userTel);
        return this.getOne(queryWrapper);
    }

    @Override
    public Boolean checkIsDisabled(String id) {

        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getId, id);

        wrapper.select(SysUser::getDisableFlag);
        SysUser one = this.getOne(wrapper);

        return one == null || one.getDisableFlag() == 1;
    }

    @Override
    public void saveUserRemark(String userId, String remark) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setRemark(remark);
        this.updateById(user);
    }

    @Override
    public void checkClockRepeat(SysUser sysUser) {
        List<String> parentIds = new ArrayList<>();
        if (StringUtils.isNotBlank(sysUser.getId()) && !"0" .equals(sysUser.getId())) {
            parentIds.add(sysUser.getId());
        }
        if (StringUtils.isNotBlank(sysUser.getParentId()) && !"0" .equals(sysUser.getParentId())) {
            parentIds.add(sysUser.getParentId());
        }

        if (
                StringUtils.isNotBlank(sysUser.getId())
                        && StringUtils.isNotBlank(sysUser.getParentId())
                        && !"0" .equals(sysUser.getParentId())
                        && sysUser.getId().equals(sysUser.getParentId())) {
            {
                throw new BusinessException("上级不能是自己");
            }
        }

        if(StringUtils.isNotBlank(sysUser.getParentId())  && !"0" .equals(sysUser.getParentId())) {
            SysUser parentUser = this.getById(sysUser.getParentId());
            while (
                    parentUser != null
                            && StringUtils.isNotBlank(parentUser.getParentId())
                            && !"0" .equals(sysUser.getParentId())) {
                if (parentIds.contains(parentUser.getParentId())) {
                    throw new BusinessException("上级出现死循环，请检查");
                } else {
                    parentIds.add(parentUser.getParentId());
                    parentUser = this.getById(parentUser.getParentId());
                }
            }
        }
    }

    @Override
    public List<SysUser> getAllUserListExceptSelf() {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(SysUser::getId,LoginContextHolder.get().getUserId());
        return this.list(queryWrapper);
    }

    @Override
    public void saveUserDetail(SysUserDetail sysUserDetail) {
        //检查上级是否会出现死循环
        this.checkClockRepeat(sysUserDetail.getUserBasicInfo());
        if (StringUtils.isBlank(sysUserDetail.getUserBasicInfo().getId())) {
            //新增
            //生成用户编号
            String userNo = generateUserNo();
            sysUserDetail.getUserBasicInfo().setUserNo(userNo);
            sysUserDetail.getUserBasicInfo().setPhoneLoginFlag(1);
            //设置默认密码
            sysUserDetail.getUserBasicInfo().setUserPwd(defaultPwd);
        }
        this.saveOrUpdate(sysUserDetail.getUserBasicInfo());
        for (SysUserCertificate item : sysUserDetail.getCertificateList()) {
            item.setUserId(sysUserDetail.getUserBasicInfo().getId());
        }
        for (SysUserIdcard item : sysUserDetail.getIdcardList()) {
            item.setUserId(sysUserDetail.getUserBasicInfo().getId());
        }
        for (SysUserContract item : sysUserDetail.getContractList()) {
            item.setUserId(sysUserDetail.getUserBasicInfo().getId());
        }
        for (SysUserHealthReport item : sysUserDetail.getHealthReportList()) {
            item.setUserId(sysUserDetail.getUserBasicInfo().getId());
        }
        userCertificateService.saveUserCertificates(sysUserDetail.getCertificateList());
        userIdcardService.saveUserIdcards(sysUserDetail.getIdcardList());
        userContractService.saveUserContracts(sysUserDetail.getContractList());
        sysUserHealthReportService.saveUserHealthReport(sysUserDetail.getHealthReportList());

        //保存用户菜单
        List<String> rightIdList = sysUserDetail.getRightIdList();
        if (rightIdList != null && rightIdList.size() > 0) {
            List<SysUser2Right> user2RightList = new ArrayList<>();
            for (String rightId : rightIdList) {
                SysUser2Right user2Right = new SysUser2Right();
                user2Right.setUserId(sysUserDetail.getUserBasicInfo().getId());
                user2Right.setRightId(rightId);
                user2Right.setSortNo(0);
                user2RightList.add(user2Right);
            }
            sysUser2RightService.saveBatch(user2RightList);
        }
    }

    //生成用户编号
    private String generateUserNo() {
        String userNoPrefix = "ERP";
        //获取目前的用户count
        Integer count = this.baseMapper.getAllCount();
        //将数字转为四位字符串
        String countStr = String.format("%03d", count);
        //拼接用户编号
        return userNoPrefix + countStr;
    }

    @Override
    public IPage<SysUser> listByPage(UserListPageParamsVo vo) {
        IPage<SysUser> page = new Page<>(vo.getCurrent(), vo.getPageSize());
        page.setCurrent(vo.getCurrent());
        page.setPages(vo.getPageSize());
        //page = this.baseMapper.listByPage(page,vo);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(vo.getNames())) {
            //根据姓名、部门、职位搜索
            queryWrapper.lambda().and(qw -> {
                qw.like(SysUser::getUserName, vo.getNames())
                        .or().like(SysUser::getDepartName, vo.getNames())
                        .or().like(SysUser::getRoleName, vo.getNames());
            });
        }
        if (StringUtils.isNotBlank(vo.getContactNos())) {
            //根据电话号码、微信、QQ搜索
            queryWrapper.lambda().and(qw -> {
                qw.like(SysUser::getUserTel, vo.getContactNos())
                        .or().like(SysUser::getWechat, vo.getContactNos())
                        .or().like(SysUser::getQq, vo.getContactNos());
            });
        }

        if (vo.getDates() != null) {
            //根据入职日期、转正日期、合同到期日期搜索
            queryWrapper.lambda().and(qw -> {
                qw.eq(SysUser::getEntryDate, vo.getDates())
                        .or().eq(SysUser::getStanfordDate, vo.getDates())
                        .or().eq(SysUser::getContractExpireDate, vo.getDates());
            });
        }

        if (vo.getFilters().getDepartName() != null && vo.getFilters().getDepartName().size() > 0) {
            queryWrapper.lambda().in(SysUser::getDepartName, vo.getFilters().getDepartName());
        }
        if (vo.getFilters().getRoleName() != null && vo.getFilters().getRoleName().size() > 0) {
            queryWrapper.lambda().in(SysUser::getRoleName, vo.getFilters().getRoleName());
        }
        if (StringUtils.isNotBlank(vo.getSorter().getOrder())) {
            String field = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, vo.getSorter().getField());
            if (vo.getSorter().getOrder().equals("ascend")) {
                queryWrapper.orderByAsc(field);
            } else {
                queryWrapper.orderByDesc(field);
            }
        }
        this.page(page, queryWrapper);
        return page;
    }

    @Override
    public List<String> listUserIdByLikeName(String name) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>(new SysUser());
        queryWrapper.lambda().like(SysUser::getUserName, name);

        List<SysUser> sysUsers = this.list(queryWrapper);
        List<String> userIds = new ArrayList<>();
        for (SysUser sysUser : sysUsers) {
            userIds.add(sysUser.getId());
        }
        return userIds;

    }
}
